﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using CSBackup_Web.Sources.Override;
using CSBackup_Web.Sources.Legacy;

namespace CSBackup_Web.Sources.ui_Legacy
{
    using Directory = System.IO.Directory;
    public static class frmUI1
    {
        public static readonly string FOLDER = @"<文件夹>";
        public static readonly string NOEXT = @"<无后缀名文件>";

        public static void CleanUpPrj(ProjectInfo curPrj)
        {
            if (curPrj != null)
            {
                curPrj.Clear();
            }
            else
            {
                curPrj = new ProjectInfo();
            }
            return;
        }

        /*
        private void frmUI1_Load(object sender, EventArgs e)
        {
            //清空lstvBkpFls的Items比较器
            this.lstvBkpFls.ListViewItemSorter = null;
            AdjustLvch1Width();

            //清空lstvBkpLst的Items比较器
            this.lstvBkpLst.ListViewItemSorter = null;
            AdjustLvch2Width();

            //清空lstvSysLog的Items比较器
            this.lstvSysLog.ListViewItemSorter = null;
            AdjustLvch34Width();

            //默认不使用文件类型过滤待备份文件列表
            this.cbFileTypes.Checked = false;
            this.ccbTypeFilter.Enabled = false;
            
            //默认选中全备份
            rbFullBkp.Checked = true;

            //如果没有新建或打开工程，则Tabs不可用，工程设置也不可用
            if (null == curPrj)
            {
                ShowedPrjName = string.Empty;
                EnableTabs(false);
                EnablePrjPrefMenu(false);
            }

            //登录窗口，模式化显示
            this.Show();  //显示登录窗口时也显示主界面
            loginDialog = new frmLogin();
            loginDialog.ShowDialog(this);
        }

        public void RefreshBkpTab()
        {
            if (null == curPrj)
                return;

            int cnt = 0;
            int index = 0;
            //清空待备份文件列表
            lstvBkpFls.Items.Clear();
            foreach (string file in curPrj.CurrentBackup.FileList)
            {
                lstvBkpFls.Items.Add(file);
            }
            AdjustLvch1Width();
            //加载文件类型下拉列表，这部分应该放在创建或打工工程的完成按钮的响应事件里
            this.ccbTypeFilter.Items.Clear();
            cnt = this.lstvBkpFls.Items.Count;
            if (0 == cnt)
            {
                this.ccbTypeFilter.Text = @"(过滤器不可用因为待备份文件列表为空)";
            }
            else
            {
                string txt = string.Empty;
                ArrayList filter = new ArrayList();
                CCBoxItem ccbItm = null;
                CCBoxItem ne = null;
                CCBoxItem fld = null;
                for (int i = 0; i < cnt; ++i)
                {
                    txt = this.lstvBkpFls.Items[i].Text;
                    //如果是文件夹
                    if (Directory.Exists(txt))
                    {
                        txt = FOLDER;
                    }
                    else
                    {
                        //如果没有后缀名
                        index = txt.LastIndexOf('.');
                        if (index < 0)
                            txt = NOEXT;
                        else
                            txt = txt.Substring(index);
                    }
                    if (!filter.Contains(txt))
                    {
                        filter.Add(txt);
                        ccbItm = new CCBoxItem(txt, i);
                        if (txt[0] != '.')
                        {
                            if (FOLDER == txt)
                                fld = ccbItm;
                            else
                                ne = ccbItm;
                        }
                        else
                            this.ccbTypeFilter.Items.Add(ccbItm);
                    }
                }
                if (fld != null)
                    this.ccbTypeFilter.Items.Add(fld);
                if (ne != null)
                    this.ccbTypeFilter.Items.Add(ne);
                this.ccbTypeFilter.DisplayMember = "name";
                //默认为都不选中
                cnt = this.ccbTypeFilter.Items.Count;
                for (int i = 0; i < cnt; ++i)
                {
                    this.ccbTypeFilter.SetItemChecked(i, false);
                }
            }
            //添加过滤器的过滤事件处理函数，应该先加载后缀名列表后才注册此事件以避免出错
            this.ccbTypeFilter.ItemCheck += new ItemCheckEventHandler(this.ccbTypeFilter_ItemCheck);

            return;
        }

        private void btnBrowse_Click(object sender, EventArgs e)
        {
            DialogResult ret = fbdRcvrPos.ShowDialog();
            if (DialogResult.OK == ret)
            {
                txtRcvrPos.Text = fbdRcvrPos.SelectedPath;
            }

            return;
        }

        private void tsmItmPref_Click(object sender, EventArgs e)
        {
            prefDialog = new frmNewBkpPrj();
            prefDialog.ShowDialog(this);
            return;
        }

        private void btnAll_Click(object sender, EventArgs e)
        {
            int cnt = this.lstvBkpFls.Items.Count;
            for (int i = 0; i < cnt; ++i)
            {
                this.lstvBkpFls.Items[i].Checked = true;
            }
            return;
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            int cnt = this.lstvBkpFls.Items.Count;
            for (int i = 0; i < cnt; ++i)
            {
                this.lstvBkpFls.Items[i].Checked = false;
            }
            return;
        }

        private void cbFileTypes_CheckedChanged(object sender, EventArgs e)
        {
            this.ccbTypeFilter.Enabled = !this.ccbTypeFilter.Enabled;
            if ((!this.cbFileTypes.Checked) && (0 == this.ccbTypeFilter.Items.Count))
                this.ccbTypeFilter.Text = @"(过滤器不可用因为待备份文件列表为空)";
            return;
        }

        private void btnAutoBkp_Click(object sender, EventArgs e)
        {
            autoDialog = new frmAutoBkp();
            autoDialog.ShowDialog(this);
            return;
        }

        private void btnRcvrPartial_Click(object sender, EventArgs e)
        {
            if (null == curPrj.SelectedBackup)
            {
                MessageBox.Show("请先选择一个要还原的备份！", "系统提示",
                    MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            if ((BackupInfo.BACKUP_TYPE_INC == curPrj.SelectedBackup.BkpType)
                || (BackupInfo.BACKUP_TYPE_DIFINC == curPrj.SelectedBackup.BkpType))
            {
                string msg = @"和增量有关的备份不支持部分文件恢复，" 
                    + "因为文件在多个版本里可能有较多新增和删除！";
                MessageBox.Show(msg, "系统提示",
                    MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            if ((string.Empty == txtRcvrPos.Text)
                || !Directory.Exists(txtRcvrPos.Text))
            {
                MessageBox.Show("请选择一个有效的恢复路径！");
                return;
            }
            curPrj.RecoveryPath = txtRcvrPos.Text;
            prDialog = new frmPrtRcvr();
            DialogResult ret = prDialog.ShowDialog(this);
            if (DialogResult.OK == ret)
            {
                try
                {
                    BackupInfo backupinfo = null;
                    BackupRecovery backRecovery = new BackupRecovery();
                    backRecovery.ProjectPath = curPrj.BkpPrjFile;
                    backRecovery.RecoveryPath = txtRcvrPos.Text.ToString();

                    List<CSBackup.Src.Override.FileInfo> files 
                        = curPrj.SelectedFileList;
                    List<CSBackup.Src.Override.FileInfo> dirs 
                        = curPrj.SelectedDirList;

                   List<String> filesToMarshal = new List<String>();
                   List<String> dirsToMarshal = new List<String>();
                   List<String> difToMarshal = new List<String>();

                    //将选中的文件名放入字符串数组中
                    for (int i = 0; i < files.Count; i++)
                    {
                        if (files[i].Selected)
                            filesToMarshal.Add(files[i].FileName);
                    }
                    //将选中的目录路径放入字符串数组中
                    for (int i = 0; i < dirs.Count; i++)
                    {
                        dirsToMarshal.Add(dirs[i].FileName);
                    }

                    for (int i = 0; i < files.Count; i++)
                    {
                        if (files[i].Selected)
                            difToMarshal.Add(files[i].DiffName);
                    }
                    //将字符串数组放入后台操作线程中
                    backRecovery.FileList = filesToMarshal;
                    backRecovery.DirList = dirsToMarshal;
                    backRecovery.DifList = difToMarshal;
                    backRecovery.Bar = this.pbProgress;
                    backupinfo = curPrj.SelectedBackup;

                    //恢复部分文件
                    if (backupinfo != null && curPrj != null)
                        backRecovery.RecoveryPartRecoveryPoint(backupinfo);

                }
                catch (Exception exception)
                {
                    MessageBox.Show(exception.Message);
                }
            }
            
            return;
        }

        #region
        /// <summary>
        /// 恢复整个还原点事件响应
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnRcvrAll_Click(object sender, EventArgs e)
        {
            if (null == curPrj.SelectedBackup)
            {
                MessageBox.Show("请先选择一个要还原的备份！", "系统提示",
                    MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            if ((string.Empty == txtRcvrPos.Text)
                || !Directory.Exists(txtRcvrPos.Text))
            {
                MessageBox.Show("请选择一个有效的恢复路径！");
                return;
            }

            DialogResult dr = MessageBox.Show("警告：恢复还原点操作会覆盖恢复路径下的任何同名文件，确认继续吗？", "系统提示", 
                MessageBoxButtons.YesNo, MessageBoxIcon.Information);
            if (DialogResult.No == dr)
                return;
            
            try
            {
                BackupInfo backupinfo = null;
                BackupRecovery backRecovery = new BackupRecovery();
                backRecovery.ProjectPath = curPrj.BkpPrjFile; 
                backRecovery.RecoveryPath = txtRcvrPos.Text.ToString();
                backRecovery.Bar = this.pbProgress;
                backupinfo = curPrj.SelectedBackup;
                if(backupinfo !=null && curPrj!=null)
                    backRecovery.RecoveryWholeRecoveryPoint(backupinfo);
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message);
            }

        }

        #endregion

        private void btnBkpNow_Click(object sender, EventArgs e)
        {
            if (null == curPrj)
                return;
            //如果尚未执行过全备份，则必须先执行一次全备份才能执行其他类型备份
            if (!rbFullBkp.Checked && (0 == curPrj.FullBackupList.Count))
            {
                MessageBox.Show("在执行其他类型备份之前必须先对所有文件执行一次全备份！", 
                    "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            //如果是第一次执行全备份，要求所有文件都要全备份
            if (rbFullBkp.Checked && (0 == curPrj.FullBackupList.Count))
            {
                if (lstvBkpFls.CheckedItems.Count != lstvBkpFls.Items.Count)
                {
                    MessageBox.Show("第一次执行全备份时必须备份所有文件！",
                    "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
            }
            if (this.lstvBkpFls.CheckedItems.Count == 0)
                return;
            List<string> selected = new List<string>();
            foreach (ListViewItem item in this.lstvBkpFls.CheckedItems)
            {
                selected.Add(item.SubItems[0].Text);
            }

            string type = null;
            if (this.rbFullBkp.Checked)
            {
                type = (string)this.rbFullBkp.Tag;
            }
            else if (this.rbDiffBkp.Checked)
            {
                type = (string)this.rbDiffBkp.Tag;
            }
            else if (this.rbIncBkp.Checked)
            {
                type = (string)this.rbIncBkp.Tag;
            }
            else if (this.rbDiffIncBkp.Checked)
            {
                type = (string)this.rbDiffIncBkp.Tag;
            }

            string granularity = null;
            if (this.rbGrainBlock.Checked)
            {
                granularity = (string)this.rbGrainBlock.Tag;
            }
            else if (this.rbGrainFile.Checked)
            {
                granularity = (string)this.rbGrainFile.Tag;
            }
            CSBackup.Src.Override.BackupWorker bw = new BackupWorker(this.curPrj.BkpPrjFile, selected, type, null,granularity);
            bw.Worker_ProgressChangedEventHandler = this.worker_ProgressChanged;
            bw.Worker_ProgressCompleteEventHandler = this.backupFinish;
            bw.RunWorkerAsync();
        }

        private void backupFinish()
        {
            string bkpFile = curPrj.BkpPrjFile;
            CleanUpPrj();
            ToolConfigFile.LoadPrjFromFile(curPrj, bkpFile);
            RefreshBkpTab();  //刷新备份Tab
        }

        private void cbbBkpLsts_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (null == curPrj)
                return;

            lstvBkpLst.Items.Clear();
            curPrj.SelectedBackup = null;
            List<BackupInfo> list = null;
            switch (cbbBkpLsts.SelectedIndex)
            {
                case 0:
                    list = curPrj.FullBackupList;
                    break;
                case 1:
                    list = curPrj.IncBackupList;
                    break;
                case 2:
                    list = curPrj.DiffBackupList;
                    break;
                default:
                    list = curPrj.DiffIncBackupList;
                    break;
            }
            foreach (BackupInfo bkpInfo in list)
            {
                lstvBkpLst.Items.Add(bkpInfo.BkpName);
            }
            return;
        }

        private void lstvBkpLst_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (0 == lstvBkpLst.SelectedIndices.Count)
                return;
            int index = lstvBkpLst.SelectedIndices[0];
            if ((index < 0) || (index >= lstvBkpLst.Items.Count))
                return;
            List<BackupInfo> list = null;
            switch (cbbBkpLsts.SelectedIndex)
            {
                case 0:
                    list = curPrj.FullBackupList;
                    break;
                case 1:
                    list = curPrj.IncBackupList;
                    break;
                case 2:
                    list = curPrj.DiffBackupList;
                    break;
                default:
                    list = curPrj.DiffIncBackupList;
                    break;
            }
            string pos = string.Empty;
            BackupInfo bkpInfo = list[index];
            curPrj.SelectedBackup = bkpInfo;
            lblBkpWay.Text = bkpInfo.BkpType;
            lblBkpTime.Text = bkpInfo.BkpTime;
            lblBkpSize.Text = bkpInfo.BkpFileSize;
            lblBkpCnt.Text = bkpInfo.BkpFileAmount;
            lblBkpDpnd.Text = bkpInfo.BkpDepended;
            pos = bkpInfo.BkpLocation;
            pos = pos.Substring(0, pos.LastIndexOf('\\'));
            if (pos.Length > 43)  //43是界面上此位置能显示的最大字符数
            {
                ttipUI1.SetToolTip(lblBkpPos, pos);
                pos = pos.Substring(0, pos.IndexOf('\\') + 1) 
                    + "..." + pos.Substring(pos.LastIndexOf('\\'));
            }
            lblBkpPos.Text = pos;

            return;
        }

        private void tabContainer_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (tpPage2 == tabContainer.SelectedTab)
            {
                cbbBkpLsts.SelectedIndex = -1;
                cbbBkpLsts.Text = "<请选择一个备份列表...>";
            }

            if (tpPage3 == tabContainer.SelectedTab)
            {
                LoadOldLogFile();
            }
            return;
        }

        private void rbFullBkp_CheckedChanged(object sender, EventArgs e)
        {
            rbGrainBlock.Enabled = !rbFullBkp.Checked;
            rbGrainFile.Enabled = !rbFullBkp.Checked;
            return;
        }

        private void tsmItmQuit_Click(object sender, EventArgs e)
        {
            DialogResult ret = MessageBox.Show("确定退出系统？", "系统提示",
                MessageBoxButtons.YesNo, MessageBoxIcon.Information);
            if (DialogResult.Yes == ret)
                Application.Exit();
            return;
        }
        */

       

        /*
        /// <summary>
        /// 此函数能正确执行的前提是，无论是原来C++代码产生的日志，
        /// 还是以后新写的日志模块产生的日志，每一条日志记录的前
        /// “10”个字符记录的都是日期，且格式是“yyyy-MM-dd”
        /// </summary>
        private void btnFilterLog_Click(object sender, EventArgs e)
        {
            int cnt = 0;
            int ret = 0;
            string start = string.Empty;
            string end = string.Empty;
            string format = @"yyyy-MM-dd";
            ListViewItem itm = null;

            start = dtpStart.Value.ToString(format);
            end = dtpEnd.Value.ToString(format);
            ret = String.Compare(start, end);
            if (ret > 0)
            {
                MessageBox.Show("起始日期不能超过结束日期！", "系统提示", 
                    MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            lstvSysLog.Enabled = false;
            if (null == sysLogs)
            {
                cnt = lstvSysLog.Items.Count;
                sysLogs = new ArrayList(cnt);

                for (int i = 0; i < cnt; ++i)
                {
                    sysLogs.Add(lstvSysLog.Items[0]);
                    lstvSysLog.Items.RemoveAt(0);
                }
            }
            else
            {
                lstvSysLog.Items.Clear();
            }
            cnt = sysLogs.Count;
            for (int i = 0; i < cnt; ++i)
            {
                itm = sysLogs[i] as ListViewItem;
                ret = String.Compare(itm.Text.Substring(0, 10), start);
                if (ret < 0)
                    continue;
                ret = String.Compare(itm.Text.Substring(0, 10), end);
                if (ret > 0)
                    continue;
                lstvSysLog.Items.Add(itm);
            }
            lstvSysLog.Enabled = true;

            return;
        }

        private void tsmItmShut_Click(object sender, EventArgs e)
        {
            tabContainer.SelectedTab = tpPage1;
            cbFileTypes.Checked = false;
            ccbTypeFilter.Enabled = false;
            rbFullBkp.Checked = true;
            rbGrainBlock.Checked = true;
            cbBkpSelfSep.Checked = false;
            lstvBkpFls.Items.Clear();
            ShowedPrjName = string.Empty;
            curPrj = null;
            EnableTabs(false);
            EnablePrjPrefMenu(false);
            SetProcStatus(@"请新建或打开一个备份工程", Color.Red);
            return;
        }

        private void btnSSSync_Click(object sender, EventArgs e)
        {
            DialogResult dr = MessageBox.Show("自分离模式同步将删除冗余备份，确认继续吗？", 
                "系统提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
            if (DialogResult.No == dr)
                return;
            int ret = 0;
            SetProcStatus("正在执行自分离模式同步...");
            pbProgress.Minimum = 0;
            pbProgress.Maximum = 100;
            pbProgress.Value = 5;
            pbProgress.Step = 5;
            ret = BackupRecovery.SyncSelfSep(curPrj.BkpPrjFile);
            while (pbProgress.Value < pbProgress.Maximum)
                pbProgress.PerformStep();

            if (ret != 0)
            {
                SetProcStatus("自分离模式同步完成！");
            }
            else
            {
                SetProcStatus("发生未知错误，自分离同步失败！");
            }
            return;
        }

        private void btnDelAll_Click(object sender, EventArgs e)
        {
            if (null == curPrj.SelectedBackup)
            {
                MessageBox.Show("您还没有选择一个还原点，请先选择。", 
                    "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            string msg = "确定要删除这个还原点吗？此操作可能导致某些增量备份和差分备份无法正确还原！";
            msg += "如果只是希望删除冗余备份，请选择\"自分离模式同步\"操作，该操作可以安全删除冗余备份。";
            DialogResult ret = MessageBox.Show(msg, "系统提示", 
                MessageBoxButtons.YesNo, MessageBoxIcon.Information);
            if (DialogResult.No == ret)
                return;

            SetProcStatus("正在删除整个还原点...");
            pbProgress.Minimum = 0;
            pbProgress.Maximum = 100;
            pbProgress.Value = 5;
            pbProgress.Step = 5;

            int index = -1;
            int del = BackupRecovery.DelRecoveryPoint(curPrj.PrjLocation, 
                curPrj.SelectedBackup.BkpLocation, curPrj.SelectedBackup.BkpName);

            while (pbProgress.Value < pbProgress.Maximum)
                pbProgress.PerformStep();

            if (del > 0)
            {
                index = cbbBkpLsts.SelectedIndex;
                switch (index)
                {
                    case 0:
                        ToolBackupInfo.LoadFullBkpInfoList(curPrj.FullBkpPath, curPrj.FullBackupList);
                        break;
                    case 1:
                        ToolBackupInfo.LoadIncBkpInfoList(curPrj.IncBkpPath, curPrj.IncBackupList);
                        break;
                    case 2:
                        ToolBackupInfo.LoadDiffBkpInfoList(curPrj.DiffBkpPath, curPrj.DiffBackupList);
                        break;
                    default:
                        ToolBackupInfo.LoadDiffIncBkpInfoList(curPrj.DiffIncBkpPath, curPrj.DiffIncBackupList);
                        break;
                }
                cbbBkpLsts.SelectedIndex = -1;
                cbbBkpLsts.SelectedIndex = index;
                SetProcStatus("删除整个还原点成功！");
            }
            else
            {
                SetProcStatus("发生未知错误，删除还原点失败！");
            }
            return;
        }

        #region 取巧控制状态栏信息重置，目前只控制了进度条
        private void frmUI1_MouseMove(object sender, MouseEventArgs e)
        {
            if (pbProgress.Value == pbProgress.Maximum)
                pbProgress.Value = 0;
            return;
        }

        private void tabContainer_MouseMove(object sender, MouseEventArgs e)
        {
            if (pbProgress.Value == pbProgress.Maximum)
                pbProgress.Value = 0;
            return;
        }

        private void pnlTp1_MouseMove(object sender, MouseEventArgs e)
        {
            if (pbProgress.Value == pbProgress.Maximum)
                pbProgress.Value = 0;
            return;
        }

        private void pnlTp2_MouseMove(object sender, MouseEventArgs e)
        {
            if (pbProgress.Value == pbProgress.Maximum)
                pbProgress.Value = 0;
            return;
        }

        private void pnlTp3_MouseMove(object sender, MouseEventArgs e)
        {
            if (pbProgress.Value == pbProgress.Maximum)
                pbProgress.Value = 0;
            return;
        }
        #endregion

        private void 自动备份ToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            frmBkpSvc svcDialog = new frmBkpSvc();
            svcDialog.Show(this);
            return;
        }
        */
    }//end of partial class
}
